Skip to content

own: name the overridable method a call reaches; immortal array globals; an array changed through a borrowing local (TSLANG 60-62) - #853

Merged
ASDAlexander77 merged 4 commits into
mainfrom
fix-own-items-60
Nov 14, 2026
Merged

ASDAlexander77 merged 4 commits into
mainfrom
fix-own-items-60

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

TSLANG_ISSUES 60, 61 and 62, found by compiling powder_sandbox's -mm=own build (native_ts_graphics as its submodule) with the compiler from main. Write-ups are in TSLANG_ISSUES.md.

60: name the overridable method a call reaches where a borrow ends

const name = this.name; for (...) this.props[i].tick(t); ... name (ntg core/rtxpt_game.ts) was refused with only "it may be released or overwritten here" at the call.

  • The cause: Prop.tick calls setNodeTransform, which calls a method of the exported, non-@final GameWorld. Another module may override that method, so the call may destroy anything.
  • The gap: TSLANG 48 named such a method only when the call itself was the virtual one.
  • The fix: the signature pass now finds the one overridable method a call's callees reach (markOverridableReached, breadth first through calls that may destroy anything, memoized per callee). The error gets a note: "'Prop.tick' calls 'setNodeTransform', which calls 'GameWorld.setGameNodeTransform'; that method may be overridden in another module by a method that does; '@Final' on the method, or on its class, says it is not".
  • When it is given: only when that method is the sole reason. No other overridable method, unknown or imported callee, or body that destroys anything is on the way, so @final on it is enough.
  • What it changes: only the diagnostic; nothing new compiles. In the sweep 48 errors carry the note: MsvcRandom (41) and GameWorld (7), ntg's @finals to add.

61: an array global nothing assigns is immortal

[CUBE_VERTICES, PLANE_VERTICES, CUBE_VERTICES], return GREEN; and const p = CAMERA_POSITION; held across calls (ntg examples) were refused as borrows of a mortal global. So was a plain const A = [1.0, 2.0] read into an array literal.

  • The cause: only a global of a class type could be immortal (own spec 25).
  • The fix: an array global qualifies on the same terms: not exported, written once by its initializer, and given a fresh array, nothing, or another immortal global's value.
  • The immortal block: the array's header, which every array release tests first. The initializing store marks it only when it is mortal, since a constant array's header is in read-only data.
  • Still bounded: an element overwritten, popped or spliced out still frees the old element, so a borrow of G[i] used after that is refused.
  • Still mortal: a global that is pushed to, or written in any other way through its address.
  • Spec: spec 25 has the amendment.

62: an array changed through a local that borrows its field

const model = this.refractionModel; ... model.push(0.0); (ntg examples/ray_tracing_extended.ts and its NRI ports) was refused: "borrows a field and cannot be stored, returned or captured".

  • The cause: push, pop, unshift, shift and splice take the slot that holds the array's header, and that was taken as the local keeping the field's value.
  • The fix: the slot holds the field's array, so each such op through the local is now a use of the borrow (collectBorrowerUses).
  • Still refused: an element read before a pop and used after it; the field given another array before a use; the local returned.
  • A field with no array yet: a field holding a null header (never given an array) gets one in the local's slot only, which nothing frees. That is undefined in TypeScript terms, as the array spec's ruling T4-D accepts for a parameter.

Effect on the sweep (276 sources, every facts object built)

  • Sources failing: 126 → 119. Now compiling: ptlas.ts, ray_tracing_reflection.ts, collision.ts, nvrhi_direct.ts, async_compute_bloom.ts, msaa.ts, texture_compression_comparison.ts.
  • Errors: 907 → 807.
  • ray_tracing_reflection_nri.ts: 29 errors → 1.

Tests

  • New tests: 00tslang_issue_60.ts, 00tslang_issue_61.ts and 00tslang_issue_62.ts, under every model, JIT and compiled.
  • New own error tests: own_err_overridable_reached, own_err_immortal_array_element_overwritten and own_err_borrowed_array_pushed_returned.
  • ctest (Windows Release): 7284/7284.
  • DefaultLib main (6806d40) rebuilt with this compiler, release and debug, all four models. tests.ps1 for each model is running; results to follow in a comment.

🤖 Generated with Claude Code

ASDAlexander77 and others added 4 commits November 14, 2026 16:33
…TSLANG 60)

`this.props[i].tick(t)` (native_ts_graphics core/rtxpt_game.ts), where `Prop.tick` reaches a method of
an exported class through `setNodeTransform`, ended borrows with no reason given: TSLANG 48 named the
method only for a direct virtual call. The signature pass now finds the one overridable method a
call's callees reach (markOverridableReached, when it is the only reason they may destroy anything)
and the error notes it with the way to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`[CUBE_VERTICES, PLANE_VERTICES]`, `return GREEN;` and `const p = CAMERA_POSITION;` over module and
namespace arrays (native_ts_graphics examples) were refused as borrows of a mortal global: only a
class-typed global could be immortal (own spec 25). An array global written once by its initializer
is now one too; its header is the immortal block (marked only when mortal: a constant array's is in
read-only data), and its elements are still freed when overwritten.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… of the borrow (TSLANG 62)

`const model = this.refractionModel; model.push(0.0)` (native_ts_graphics examples) was refused as the
local keeping the field's value: push, pop, unshift, shift and splice take the local's slot. The slot
holds the field's array, so they are uses of the borrow (collectBorrowerUses).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77

Copy link
Copy Markdown
Owner Author

DefaultLib tests.ps1 with this branch's compiler (DefaultLib main at 6806d40 rebuilt, release and debug, all four models). No failures; the skips are the usual by-design ones.

model release compile release jit debug compile debug jit
own 219/225, 6 skipped 219/225, 6 skipped 219/225, 6 skipped 219/225, 6 skipped
rc 221/225, 4 skipped 221/225, 4 skipped 221/225, 4 skipped 221/225, 4 skipped
gc 224/225, 1 skipped 224/225, 1 skipped 224/225, 1 skipped 224/225, 1 skipped
none 221/225, 4 skipped 221/225, 4 skipped 221/225, 4 skipped 221/225, 4 skipped

@ASDAlexander77
ASDAlexander77 merged commit 8fe1758 into main Nov 14, 2026
8 checks passed
@ASDAlexander77
ASDAlexander77 deleted the fix-own-items-60 branch November 14, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant